home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / emacs.lha / emacs-19.16 / lisp / replace.el < prev    next >
Lisp/Scheme  |  1993-07-04  |  22KB  |  577 lines

  1. ;;; replace.el --- replace commands for Emacs.
  2.  
  3. ;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
  4.  
  5. ;; This file is part of GNU Emacs.
  6.  
  7. ;; GNU Emacs is free software; you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation; either version 2, or (at your option)
  10. ;; any later version.
  11.  
  12. ;; GNU Emacs is distributed in the hope that it will be useful,
  13. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. ;; GNU General Public License for more details.
  16.  
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs; see the file COPYING.  If not, write to
  19. ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21. ;;; Commentary:
  22.  
  23. ;; This package supplies the string and regular-expression replace functions
  24. ;; documented in the Emacs user's manual.
  25.  
  26. ;;; Code:
  27.  
  28. (defconst case-replace t "\
  29. *Non-nil means query-replace should preserve case in replacements.")
  30.  
  31. (defvar query-replace-history nil)
  32.  
  33. (defun query-replace-read-args (string)
  34.   (let (from to)
  35.     (setq from (read-from-minibuffer (format "%s: " string)
  36.                      nil nil nil
  37.                      'query-replace-history))
  38.     (setq to (read-from-minibuffer (format "%s %s with: " string from)
  39.                    nil nil nil
  40.                    'query-replace-history))
  41.     (list from to current-prefix-arg)))
  42.  
  43. (defun query-replace (from-string to-string &optional arg)
  44.   "Replace some occurrences of FROM-STRING with TO-STRING.
  45. As each match is found, the user must type a character saying
  46. what to do with it.  For directions, type \\[help-command] at that time.
  47.  
  48. Preserves case in each replacement if  case-replace  and  case-fold-search
  49. are non-nil and FROM-STRING has no uppercase letters.
  50. Third arg DELIMITED (prefix arg if interactive) non-nil means replace
  51. only matches surrounded by word boundaries.
  52.  
  53. To customize possible responses, change the \"bindings\" in `query-replace-map'."
  54.   (interactive (query-replace-read-args "Query replace"))
  55.   (perform-replace from-string to-string t nil arg)
  56.   (or unread-command-events (message "Done")))
  57. (define-key esc-map "%" 'query-replace)
  58.  
  59. (defun query-replace-regexp (regexp to-string &optional arg)
  60.   "Replace some things after point matching REGEXP with TO-STRING.
  61. As each match is found, the user must type a character saying
  62. what to do with it.  For directions, type \\[help-command] at that time.
  63.  
  64. Preserves case in each replacement if  case-replace  and  case-fold-search
  65. are non-nil and REGEXP has no uppercase letters.
  66. Third arg DELIMITED (prefix arg if interactive) non-nil means replace
  67. only matches surrounded by word boundaries.
  68. In TO-STRING, \\& means insert what matched REGEXP,
  69. and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP."
  70.   (interactive (query-replace-read-args "Query replace regexp"))
  71.   (perform-replace regexp to-string t t arg)
  72.   (or unread-command-events (message "Done")))
  73.  
  74. (defun map-query-replace-regexp (regexp to-strings &optional arg)
  75.   "Replace some matches for REGEXP with various strings, in rotation.
  76. The second argument TO-STRINGS contains the replacement strings, separated
  77. by spaces.  This command works like `query-replace-regexp' except
  78. that each successive replacement uses the next successive replacement string,
  79. wrapping around from the last such string to the first.
  80.  
  81. Non-interactively, TO-STRINGS may be a list of replacement strings.
  82.  
  83. A prefix argument N says to use each replacement string N times
  84. before rotating to the next."
  85.   (interactive
  86.    (let (from to)
  87.      (setq from (read-from-minibuffer "Map query replace (regexp): "
  88.                       nil nil nil
  89.                       'query-replace-history))
  90.      (setq to (read-from-minibuffer
  91.            (format "Query replace %s with (space-separated strings): "
  92.                from)
  93.            nil nil nil
  94.            'query-replace-history))
  95.      (list from to current-prefix-arg)))
  96.   (let (replacements)
  97.     (if (listp to-strings)
  98.     (setq replacements to-strings)
  99.       (while (/= (length to-strings) 0)
  100.     (if (string-match " " to-strings)
  101.         (setq replacements
  102.           (append replacements
  103.               (list (substring to-strings 0
  104.                        (string-match " " to-strings))))
  105.           to-strings (substring to-strings
  106.                        (1+ (string-match " " to-strings))))
  107.       (setq replacements (append replacements (list to-strings))
  108.         to-strings ""))))
  109.     (perform-replace regexp replacements t t nil arg))
  110.   (or unread-command-events (message "Done")))
  111.  
  112. (defun replace-string (from-string to-string &optional delimited)
  113.   "Replace occurrences of FROM-STRING with TO-STRING.
  114. Preserve case in each match if `case-replace' and `case-fold-search'
  115. are non-nil and FROM-STRING has no uppercase letters.
  116. Third arg DELIMITED (prefix arg if interactive) non-nil means replace
  117. only matches surrounded by word boundaries.
  118.  
  119. This function is usually the wrong thing to use in a Lisp program.
  120. What you probably want is a loop like this:
  121.   (while (search-forward OLD-STRING nil t)
  122.     (replace-match REPLACEMENT nil t))
  123. which will run faster and will not set the mark or print anything."
  124.   (interactive (query-replace-read-args "Replace string"))
  125.   (perform-replace from-string to-string nil nil delimited)
  126.   (or unread-command-events (message "Done")))
  127.  
  128. (defun replace-regexp (regexp to-string &optional delimited)
  129.   "Replace things after point matching REGEXP with TO-STRING.
  130. Preserve case in each match if case-replace and case-fold-search
  131. are non-nil and REGEXP has no uppercase letters.
  132. Third arg DELIMITED (prefix arg if interactive) non-nil means replace
  133. only matches surrounded by word boundaries.
  134. In TO-STRING, \\& means insert what matched REGEXP,
  135. and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP.
  136.  
  137. This function is usually the wrong thing to use in a Lisp program.
  138. What you probably want is a loop like this:
  139.   (while (re-search-forward REGEXP nil t)
  140.     (replace-match REPLACEMENT nil nil))
  141. which will run faster and will not set the mark or print anything."
  142.   (interactive (query-replace-read-args "Replace regexp"))
  143.   (perform-replace regexp to-string nil t delimited)
  144.   (or unread-command-events (message "Done")))
  145.  
  146. (defvar regexp-history nil
  147.   "History list for some commands that read regular expressions.")
  148.  
  149. (defalias 'delete-non-matching-lines 'keep-lines)
  150. (defun keep-lines (regexp)
  151.   "Delete all lines except those containing matches for REGEXP.
  152. A match split across lines preserves all the lines it lies in.
  153. Applies to all lines after point."
  154.   (interactive (list (read-from-minibuffer
  155.               "Keep lines (containing match for regexp): "
  156.               nil nil nil 'regexp-history)))
  157.   (save-excursion
  158.     (or (bolp) (forward-line 1))
  159.     (let ((start (point)))
  160.       (while (not (eobp))
  161.     ;; Start is first char not preserved by previous match.
  162.     (if (not (re-search-forward regexp nil 'move))
  163.         (delete-region start (point-max))
  164.       (let ((end (save-excursion (goto-char (match-beginning 0))
  165.                      (beginning-of-line)
  166.                      (point))))
  167.         ;; Now end is first char preserved by the new match.
  168.         (if (< start end)
  169.         (delete-region start end))))
  170.     (setq start (save-excursion (forward-line 1)
  171.                     (point)))
  172.     ;; If the match was empty, avoid matching again at same place.
  173.     (and (not (eobp)) (= (match-beginning 0) (match-end 0))
  174.          (forward-char 1))))))
  175.  
  176. (defalias 'delete-matching-lines 'flush-lines)
  177. (defun flush-lines (regexp)
  178.   "Delete lines containing matches for REGEXP.
  179. If a match is split across lines, all the lines it lies in are deleted.
  180. Applies to lines after point."
  181.   (interactive (list (read-from-minibuffer
  182.               "Flush lines (containing match for regexp): "
  183.               nil nil nil 'regexp-history)))
  184.   (save-excursion
  185.     (while (and (not (eobp))
  186.         (re-search-forward regexp nil t))
  187.       (delete-region (save-excursion (goto-char (match-beginning 0))
  188.                      (beginning-of-line)
  189.                      (point))
  190.              (progn (forward-line 1) (point))))))
  191.  
  192. (defalias 'count-matches 'how-many)
  193. (defun how-many (regexp)
  194.   "Print number of matches for REGEXP following point."
  195.   (interactive (list (read-from-minibuffer
  196.               "How many matches for (regexp): "
  197.               nil nil nil 'regexp-history)))
  198.   (let ((count 0) opoint)
  199.     (save-excursion
  200.      (while (and (not (eobp))
  201.          (progn (setq opoint (point))
  202.             (re-search-forward regexp nil t)))
  203.        (if (= opoint (point))
  204.        (forward-char 1)
  205.      (setq count (1+ count))))
  206.      (message "%d occurrences" count))))
  207.  
  208. (defvar occur-mode-map ())
  209. (if occur-mode-map
  210.     ()
  211.   (setq occur-mode-map (make-sparse-keymap))
  212.   (define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence))
  213.  
  214. (defvar occur-buffer nil)
  215. (defvar occur-nlines nil)
  216. (defvar occur-pos-list nil)
  217.  
  218. (defun occur-mode ()
  219.   "Major mode for output from \\[occur].
  220. Move point to one of the occurrences in this buffer,
  221. then use \\[occur-mode-goto-occurrence] to go to the same occurrence
  222. in the buffer that the occurrences were found in.
  223. \\{occur-mode-map}"
  224.   (kill-all-local-variables)
  225.   (use-local-map occur-mode-map)
  226.   (setq major-mode 'occur-mode)
  227.   (setq mode-name "Occur")
  228.   (make-local-variable 'occur-buffer)
  229.   (make-local-variable 'occur-nlines)
  230.   (make-local-variable 'occur-pos-list))
  231.  
  232. (defun occur-mode-goto-occurrence ()
  233.   "Go to the line this occurrence was found in, in the buffer it was found in."
  234.   (interactive)
  235.   (if (or (null occur-buffer)
  236.       (null (buffer-name occur-buffer)))
  237.       (progn
  238.     (setq occur-buffer nil
  239.           occur-pos-list nil)
  240.     (error "Buffer in which occurrences were found is deleted")))
  241.   (let* ((occur-number (save-excursion
  242.              (beginning-of-line)
  243.              (/ (1- (count-lines (point-min)
  244.                          (save-excursion
  245.                            (beginning-of-line)
  246.                            (point))))
  247.                 (cond ((< occur-nlines 0)
  248.                    (- 2 occur-nlines))
  249.                   ((> occur-nlines 0)
  250.                    (+ 2 (* 2 occur-nlines)))
  251.                   (t 1)))))
  252.      (pos (nth occur-number occur-pos-list)))
  253.     (pop-to-buffer occur-buffer)
  254.     (goto-char (marker-position pos))))
  255.  
  256. (defvar list-matching-lines-default-context-lines 0
  257.   "*Default number of context lines to include around a `list-matching-lines'
  258. match.  A negative number means to include that many lines before the match.
  259. A positive number means to include that many lines both before and after.")
  260.  
  261. (defalias 'list-matching-lines 'occur)
  262.  
  263. (defun occur (regexp &optional nlines)
  264.   "Show all lines in the current buffer containing a match for REGEXP.
  265.  
  266. If a match spreads across multiple lines, all those lines are shown.
  267.  
  268. Each line is displayed with NLINES lines before and after, or -NLINES
  269. before if NLINES is negative.
  270. NLINES defaults to `list-matching-lines-default-context-lines'.
  271. Interactively it is the prefix arg.
  272.  
  273. The lines are shown in a buffer named `*Occur*'.
  274. It serves as a menu to find any of the occurrences in this buffer.
  275. \\[describe-mode] in that buffer will explain how."
  276.   (interactive (list (let* ((default (car regexp-history))
  277.                 (input 
  278.                  (read-from-minibuffer
  279.                   (format "List lines matching regexp (default `%s'): " default)
  280.                   nil nil nil
  281.                   'regexp-history)))
  282.                (if (> (length input) 0) input
  283.              (setcar regexp-history default)))
  284.              current-prefix-arg))
  285.   (setq nlines (if nlines (prefix-numeric-value nlines)
  286.          list-matching-lines-default-context-lines))
  287.   (let ((first t)
  288.     (buffer (current-buffer))
  289.     (linenum 1)
  290.     (prevpos (point-min))
  291.     (final-context-start (make-marker)))
  292. ;;;    (save-excursion
  293. ;;;      (beginning-of-line)
  294. ;;;      (setq linenum (1+ (count-lines (point-min) (point))))
  295. ;;;      (setq prevpos (point)))
  296.     (with-output-to-temp-buffer "*Occur*"
  297.       (save-excursion
  298.     (set-buffer standard-output)
  299.     (insert "Lines matching ")
  300.     (prin1 regexp)
  301.     (insert " in buffer " (buffer-name buffer) ?. ?\n)
  302.     (occur-mode)
  303.     (setq occur-buffer buffer)
  304.     (setq occur-nlines nlines)
  305.     (setq occur-pos-list ()))
  306.       (if (eq buffer standard-output)
  307.       (goto-char (point-max)))
  308.       (save-excursion
  309.     (beginning-of-buffer)
  310.     ;; Find next match, but give up if prev match was at end of buffer.
  311.     (while (and (not (= prevpos (point-max)))
  312.             (re-search-forward regexp nil t))
  313.       (goto-char (match-beginning 0))
  314.       (beginning-of-line)
  315.       (save-match-data
  316.         (setq linenum (+ linenum (count-lines prevpos (point)))))
  317.       (setq prevpos (point))
  318.       (goto-char (match-end 0))
  319.       (let* ((start (save-excursion
  320.               (goto-char (match-beginning 0))
  321.               (forward-line (if (< nlines 0) nlines (- nlines)))
  322.               (point)))
  323.          (end (save-excursion
  324.             (goto-char (match-end 0))
  325.             (if (> nlines 0)
  326.                 (forward-line (1+ nlines))
  327.                 (forward-line 1))
  328.             (point)))
  329.          (tag (format "%3d" linenum))
  330.          (empty (make-string (length tag) ?\ ))
  331.          tem)
  332.         (save-excursion
  333.           (setq tem (make-marker))
  334.           (set-marker tem (point))
  335.           (set-buffer standard-output)
  336.           (setq occur-pos-list (cons tem occur-pos-list))
  337.           (or first (zerop nlines)
  338.           (insert "--------\n"))
  339.           (setq first nil)
  340.           (insert-buffer-substring buffer start end)
  341.           (backward-char (- end start))
  342.           (setq tem nlines)
  343.           (while (> tem 0)
  344.         (insert empty ?:)
  345.         (forward-line 1)
  346.         (setq tem (1- tem)))
  347.           (let ((this-linenum linenum))
  348.         (set-marker final-context-start
  349.                 (+ (point) (- (match-end 0) (match-beginning 0))))
  350.         (while (< (point) final-context-start)
  351.           (if (null tag)
  352.               (setq tag (format "%3d" this-linenum)))
  353.           (insert tag ?:)
  354.           (setq tag nil)
  355.           (forward-line 1)
  356.           (setq this-linenum (1+ this-linenum))))
  357.           (while (< tem nlines)
  358.         (insert empty ?:)
  359.         (forward-line 1)
  360.         (setq tem (1+ tem))))                
  361.         (forward-line 1)))
  362.     (set-buffer standard-output)
  363.     ;; Put positions in increasing order to go with buffer.
  364.     (setq occur-pos-list (nreverse occur-pos-list))
  365.     (if (interactive-p)
  366.         (message "%d matching lines." (length occur-pos-list)))))))
  367.  
  368. ;; It would be nice to use \\[...], but there is no reasonable way
  369. ;; to make that display both SPC and Y.
  370. (defconst query-replace-help
  371.   "Type Space or `y' to replace one match, Delete or `n' to skip to next,
  372. ESC or `q' to exit, Period to replace one match and exit,
  373. Comma to replace but not move point immediately,
  374. C-r to enter recursive edit (\\[exit-recursive-edit] to get out again),
  375. C-w to delete match and recursive edit,
  376. C-l to clear the screen, redisplay, and offer same replacement again,
  377. ! to replace all remaining matches with no more questions,
  378. ^ to move point back to previous match."
  379.   "Help message while in query-replace")
  380.  
  381. (defvar query-replace-map (make-sparse-keymap)
  382.   "Keymap that defines the responses to questions in `query-replace'.
  383. The \"bindings\" in this map are not commands; they are answers.
  384. The valid answers include `act', `skip', `act-and-show',
  385. `exit', `act-and-exit', `edit', `delete-and-edit', `recenter',
  386. `automatic', `backup', and `help'.")
  387.  
  388. (define-key query-replace-map " " 'act)
  389. (define-key query-replace-map "\d" 'skip)
  390. (define-key query-replace-map [delete] 'skip)
  391. (define-key query-replace-map [backspace] 'skip)
  392. (define-key query-replace-map "y" 'act)
  393. (define-key query-replace-map "n" 'skip)
  394. (define-key query-replace-map "," 'act-and-show)
  395. (define-key query-replace-map "\e" 'exit)
  396. (define-key query-replace-map [escape] 'exit)
  397. (define-key query-replace-map "q" 'exit)
  398. (define-key query-replace-map "\r" 'exit)
  399. (define-key query-replace-map [return] 'exit)
  400. (define-key query-replace-map "." 'act-and-exit)
  401. (define-key query-replace-map "\C-r" 'edit)
  402. (define-key query-replace-map "\C-w" 'delete-and-edit)
  403. (define-key query-replace-map "\C-l" 'recenter)
  404. (define-key query-replace-map "!" 'automatic)
  405. (define-key query-replace-map "^" 'backup)
  406. (define-key query-replace-map "\C-h" 'help)
  407. (define-key query-replace-map "?" 'help)
  408. (define-key query-replace-map "\C-g" 'quit)
  409. (define-key query-replace-map "\C-]" 'quit)
  410.  
  411. (defun perform-replace (from-string replacements
  412.                 query-flag regexp-flag delimited-flag
  413.             &optional repeat-count map)
  414.   "Subroutine of `query-replace'.  Its complexity handles interactive queries.
  415. Don't use this in your own program unless you want to query and set the mark
  416. just as `query-replace' does.  Instead, write a simple loop like this:
  417.   (while (re-search-forward \"foo[ \t]+bar\" nil t)
  418.     (replace-match \"foobar\" nil nil))
  419. which will run faster and do exactly what you probably want."
  420.   (or map (setq map query-replace-map))
  421.   (let ((nocasify (not (and case-fold-search case-replace
  422.                 (string-equal from-string
  423.                       (downcase from-string)))))
  424.     (literal (not regexp-flag))
  425.     (search-function (if regexp-flag 're-search-forward 'search-forward))
  426.     (search-string from-string)
  427.     (real-match-data nil)        ; the match data for the current match
  428.     (next-replacement nil)
  429.     (replacement-index 0)
  430.     (keep-going t)
  431.     (stack nil)
  432.     (next-rotate-count 0)
  433.     (replace-count 0)
  434.     (lastrepl nil)            ;Position after last match considered.
  435.     (match-again t))
  436.     (if (stringp replacements)
  437.     (setq next-replacement replacements)
  438.       (or repeat-count (setq repeat-count 1)))
  439.     (if delimited-flag
  440.     (setq search-function 're-search-forward
  441.           search-string (concat "\\b"
  442.                     (if regexp-flag from-string
  443.                       (regexp-quote from-string))
  444.                     "\\b")))
  445.     (push-mark)
  446.     (undo-boundary)
  447.     ;; Loop finding occurrences that perhaps should be replaced.
  448.     (while (and keep-going
  449.         (not (eobp))
  450.         (funcall search-function search-string nil t)
  451.         ;; If the search string matches immediately after
  452.         ;; the previous match, but it did not match there
  453.         ;; before the replacement was done, ignore the match.
  454.         (if (or (eq lastrepl (point))
  455.             (and regexp-flag
  456.                  (eq lastrepl (match-beginning 0))
  457.                  (not match-again)))
  458.             (if (eobp)
  459.             nil
  460.               ;; Don't replace the null string 
  461.               ;; right after end of previous replacement.
  462.               (forward-char 1)
  463.               (funcall search-function search-string nil t))
  464.           t))
  465.  
  466.       ;; Save the data associated with the real match.
  467.       (setq real-match-data (match-data))
  468.  
  469.       ;; Before we make the replacement, decide whether the search string
  470.       ;; can match again just after this match.
  471.       (if regexp-flag
  472.       (setq match-again (looking-at search-string)))
  473.       ;; If time for a change, advance to next replacement string.
  474.       (if (and (listp replacements)
  475.            (= next-rotate-count replace-count))
  476.       (progn
  477.         (setq next-rotate-count
  478.           (+ next-rotate-count repeat-count))
  479.         (setq next-replacement (nth replacement-index replacements))
  480.         (setq replacement-index (% (1+ replacement-index) (length replacements)))))
  481.       (if (not query-flag)
  482.       (progn
  483.         (store-match-data real-match-data)
  484.         (replace-match next-replacement nocasify literal)
  485.         (setq replace-count (1+ replace-count)))
  486.     (undo-boundary)
  487.     (let (done replaced key def)
  488.       ;; Loop reading commands until one of them sets done,
  489.       ;; which means it has finished handling this occurrence.
  490.       (while (not done)
  491.         (message "Query replacing %s with %s: "
  492.              from-string next-replacement)
  493.         (setq key (read-event))
  494.         (setq key (vector key))
  495.         (setq def (lookup-key map key))
  496.         ;; Restore the match data while we process the command.
  497.         (store-match-data real-match-data)
  498.         (cond ((eq def 'help)
  499.            (with-output-to-temp-buffer "*Help*"
  500.              (princ
  501.               (concat "Query replacing "
  502.                   (if regexp-flag "regexp " "")
  503.                   from-string " with "
  504.                   next-replacement ".\n\n"
  505.                   (substitute-command-keys
  506.                    query-replace-help)))))
  507.           ((eq def 'exit)
  508.            (setq keep-going nil)
  509.            (setq done t))
  510.           ((eq def 'backup)
  511.            (let ((elt (car stack)))
  512.              (goto-char (car elt))
  513.              (setq replaced (eq t (cdr elt)))
  514.              (or replaced
  515.              (store-match-data (cdr elt)))
  516.              (setq stack (cdr stack))))             
  517.           ((eq def 'act)
  518.            (or replaced
  519.                (replace-match next-replacement nocasify literal))
  520.            (setq done t replaced t))
  521.           ((eq def 'act-and-exit)
  522.            (or replaced
  523.                (replace-match next-replacement nocasify literal))
  524.            (setq keep-going nil)
  525.            (setq done t replaced t))
  526.           ((eq def 'act-and-show)
  527.            (if (not replaced)
  528.                (progn
  529.              (replace-match next-replacement nocasify literal)
  530.              (setq replaced t))))
  531.           ((eq def 'automatic)
  532.            (or replaced
  533.                (replace-match next-replacement nocasify literal))
  534.            (setq done t query-flag nil replaced t))
  535.           ((eq def 'skip)
  536.            (setq done t))
  537.           ((eq def 'recenter)
  538.            (recenter nil))
  539.           ((eq def 'edit)
  540.            (store-match-data
  541.             (prog1 (match-data)
  542.               (save-excursion (recursive-edit))))
  543.            ;; Before we make the replacement,
  544.            ;; decide whether the search string
  545.            ;; can match again just after this match.
  546.            (if regexp-flag
  547.                (setq match-again (looking-at search-string))))
  548.           ((eq def 'delete-and-edit)
  549.            (delete-region (match-beginning 0) (match-end 0))
  550.            (store-match-data
  551.             (prog1 (match-data)
  552.               (save-excursion (recursive-edit))))
  553.            (setq replaced t))
  554.           (t
  555.            (setq keep-going nil)
  556.            (setq unread-command-events
  557.              (append (listify-key-sequence key)
  558.                  unread-command-events))
  559.            (setq done t))))
  560.       ;; Record previous position for ^ when we move on.
  561.       ;; Change markers to numbers in the match data
  562.       ;; since lots of markers slow down editing.
  563.       (setq stack
  564.         (cons (cons (point)
  565.                 (or replaced
  566.                 (mapcar
  567.                  (function (lambda (elt)
  568.                          (and elt
  569.                           (marker-position elt))))
  570.                  (match-data))))
  571.               stack))
  572.       (if replaced (setq replace-count (1+ replace-count)))))
  573.       (setq lastrepl (point)))
  574.   (and keep-going stack)))
  575.  
  576. ;;; replace.el ends here
  577.